/*                    BioJava development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/copyleft/lesser.html
 *
 * Copyright for this code is held jointly by the individual
 * authors.  These should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims,
 * or to join the biojava-l mailing list, visit the home page
 * at:
 *
 *      http://www.biojava.org/
 *
 * @author Thomas Down
 *
 */
package dasregistry;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

import org.biojava.dasobert.dasregistry.*;
import org.biojava.services.das.registry.DasClient;


public class dasClientLink {
	
	private static final String ENSEMBL_LABEL = "ENSEMBL";
	
	
	private  static DasClient ENSEMBL_DAS_CLIENT;
	
	static {
		ENSEMBL_DAS_CLIENT = new DasClient();
		URL ensurl = null;
		try {
			ensurl = new URL("http://www.ensembl.org");			
		} catch (MalformedURLException e){
			e.printStackTrace();			
		}
		ENSEMBL_DAS_CLIENT.setHomepage(ensurl);
		ENSEMBL_DAS_CLIENT.setName("Ensembl");
		ENSEMBL_DAS_CLIENT.setIconPath("ensembl.png");
	}

	/** provides the links that are shown so das sources can be automatically enabled in DAS clients 
	 * config is done in the dasregistrycfg.xml file.

	 * arguments:
	 * clients - all available Das Clients
	 * ds the das source for which the links should be created
	 * showClientName - a flag to indicate if the name of the client should be provided
	 * showIcon - a flag to indicate if the image should be provided

	 * %id will be replaced with the unique ID of a DAS source 
	 * %url will be replaced with the url of a DAS source 
	 * %nickname will be replaced with the nickname of a DAS source 
	 * %testcode will be replaced with the testcode of a DAS source
	 *
	 * a location like 2R:500,1000 contains
	 * reference: 2R start: 500 stop: 1000 
	 * %reference only for chromosomal coordinates - the reference of the location 
	 * %start only for chromosomal coordinates the start of the location 
	 * %stop only for chromosomal coordinates the end of the location 
	 * 
	 * ensembl specific things ...
	 * %ensurl is the url of the server without the last bit (which e! calls dsn - das source name)
	 * %dsn    the last bit of the url 
	 * @param clients 
	 * @param ds 
	 * @param showLink 
	 * @param showClientName 
	 * @param showIcon 
	 * @return the links for the das clients

	* @deprecated since March 2007 - please use ActivationURLCreator instead
	 */
	public static String[] getDasClientLinks(DasClient[] clients, 
			DasSource ds,
			boolean showLink, 
			boolean showClientName, 
			boolean showIcon){

		List links = new ArrayList();

		List usedCoords = new ArrayList();
		
		if ( clients != null ) {
						
			
			DasCoordinateSystem[] coordSys = ds.getCoordinateSystem();			

			for ( int i=0;i<clients.length;i++){

				DasClient client =clients[i];
				Map[] coordMap = client.getCoordSysMap();
				for ( int k = 0 ; k< coordMap.length ; k++ ) {
					Map m = coordMap[k];
					String msg = "" ;
					String tmpcoord = (String) m.get("name");
					for (int j=0;j<coordSys.length;j++){
						DasCoordinateSystem cs = coordSys[j];

						// check if this DAS client has an auto activation url for this coordinate system
						if ( tmpcoord.equals(cs.toString())) {

							usedCoords.add(cs);
							
							String activationString = (String) m.get("activate");
							String testCode = cs.getTestCode();
							String ac = getActivationString(testCode, ds, client, activationString, showLink, showClientName, showIcon);
							
							msg += ac;
						
						
							
						}		    
					}
					if ( ! msg.equals(""))
						links.add(msg);	
				}

			}
		} 
		
		// check for default Ensembl style coordiante system.
		addEnsemblLinks(links,usedCoords, ds, showLink, showClientName, showIcon);
		
		
		return (String[]) links.toArray(new String[links.size()]);
	}
	
	
	private static String getActivationString(String testCode,
			DasSource ds,
			DasClient client,
			String activationString,
			boolean showLink,
			boolean showClientName, 
			boolean showIcon
			){
		
		String msg = "" ; // will be returned ;
		
		String reference = "";
		String start = "";
		String stop  = "";
		String[] spl = testCode.split(":");
		if (spl.length <2) {
			reference = testCode;
		} else if ( spl.length ==2) {
			reference = spl[0];
			String coordsspl = spl[1];
			String[] splc = coordsspl.split(",");
			if ( splc.length == 2 ) {
				start = splc[0];
				stop  = splc[1];
			}
		}

		String nickname  = ds.getNickname().replaceAll(" ","_");
		String url       = ds.getUrl();

//		 e! specific stuff;
		String[] urlsplit = url.split("/");
		String dsn = urlsplit[urlsplit.length-1];

		String ensurl = "";
		for ( int i=0;i<urlsplit.length-1;i++) {
			ensurl+=urlsplit[i];
			if ( i < urlsplit.length-2)
				ensurl += "/";
		}

	
		activationString = activationString.replaceAll("%id",ds.getId());
		activationString = activationString.replaceAll("%testcode",testCode);
		activationString = activationString.replaceAll("%nickname",nickname);
		activationString = activationString.replaceAll("%url",url);
		activationString = activationString.replaceAll("%reference",reference);
		activationString = activationString.replaceAll("%start",start);
		activationString = activationString.replaceAll("%stop",stop);
		activationString = activationString.replaceAll("%ensurl",ensurl);
		activationString = activationString.replaceAll("%dsn",dsn);

		if ( showLink ) {
			msg +="<a href=\"javascript:openWindow('"+ activationString+"','',600,400)\">" ;
		} else {
			msg += activationString;
		}

		if ( showIcon ) {
			String imgPath = client.getIconPath();
			if ( imgPath != null ) {
				msg +="<img src=\""+imgPath+"\" border=\"0\">";

			} else {
				msg +=client.getName().substring(0,1);

			}
		}

		if ( showClientName ) {
			msg +=client.getName();
		}
		if ( showLink) {
			msg += "</a>";
		}
		
		return msg;
	}
	
	
	private static boolean hasEnsemblLabel(String[] labels ){
		boolean hasEnsemblLabel = false;
		
		for ( int i = 0 ; i< labels.length ;i++){
			String lab = labels[i];
			if ( lab.equals(ENSEMBL_LABEL)){
				hasEnsemblLabel = true;
				break;
			}
		}
		return hasEnsemblLabel;
	}
	
	private static void addEnsemblLinks(List links,
			List usedCoords,
			DasSource ds,
			boolean showLink, 
			boolean showClientName, 
			boolean showIcon){
		
		
		if ( ! hasEnsemblLabel(ds.getLabels()))
			return;
		
		DasClient client = ENSEMBL_DAS_CLIENT;
		
		
		// we do this only for DAS sources that have the ENSEMBL label turned on...
				
		DasCoordinateSystem[] coordSys = ds.getCoordinateSystem();
		for ( int i = 0 ; i< coordSys.length ; i++){
			DasCoordinateSystem cs = coordSys[i];
			
			if ( usedCoords.contains(cs))
				continue;
			
			// this only works with Chromosomal coordinate systems ...
			if ( ! cs.getCategory().equals("Chromosome"))
				continue;
				
			// this coordinate system has already been dealt with by the manual configuration
			String activationString = "http://www.ensembl.org/";
			activationString += cs.getOrganismName().replaceAll(" ", "_");
			activationString+= "/contigview?region=%reference&amp;" +
			"vc_start=%start&amp;vc_end=%stop&amp;"+
			"add_das_source=(url=%ensurl+dsn=%dsn+type=ensembl_location_chromosome+name=%nickname+group=N+active=1)";
			
			String testCode = cs.getTestCode();
			
			String msg = getActivationString(testCode, ds, client, 
					activationString, showLink, showClientName, showIcon);
			if ( msg != "") {
				links.add(msg);
				usedCoords.add(cs);
			}
		}
		
		
	}
}
